﻿using MtApi;
using MTEA.WatchDog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MTEA.MTTask
{
    public class MTTaskExecuter: IWatchable
    {
        public static readonly MTTaskExecuter Instance = new MTTaskExecuter();

        private static string Tag = "MTTaskExecuter";
        private MtApiClient client;
        private readonly List<IMTTask> tasks;
        private readonly List<IMTTask> removeTasks;
        private MTTaskContext context;
        private ulong watchToken;
        public MtApiClient Client
        {
            get
            {
                return client;
            }
        }

        public string Name
        {
            get
            {
                return "MTTaskExecuter";
            }
        }

        private MTTaskExecuter()
        {
            tasks = new List<IMTTask>();
            removeTasks = new List<IMTTask>();
            watchToken = 10;
            MTWatchDog.Instance.AddWatchable(this);
        }
        public void Start()
        {
            client = new MtApiClient();
            Client.ConnectionStateChanged += onConnectionStateChanged;
            Client.QuoteUpdated += onQuoteUpdated;
            context = new MTTaskContext("GOLD", Client);
            MTWatchDog.Instance.Start();

           // client.BeginConnect(8222);

        }

        private void onQuoteUpdated(object sender, string symbol, double bid, double ask)
        {
            watchToken++;
            removeTasks.Clear();
            foreach(var task in tasks)
            {
                task.Execute(context);
                if(task.IsFinished)
                {
                    removeTasks.Add(task);
                }
            }

            foreach (var task in removeTasks)
            {
                tasks.Remove(task);
            }
        }

        private void onConnectionStateChanged(object sender, MtConnectionEventArgs e)
        {
            if (e.Status == MtConnectionState.Connected)
            {
                MTWatchDog.Instance.Start();
            }
        }

        public IMTTask[] GetTasks()
        {
            return tasks.ToArray();
        }

        public int AddTask(IMTTask task)
        {
            Random random = new Random();
            int id = int.MinValue;
            int count = 0;
            do
            {
                id = random.Next(0, 99);
                count = tasks.FindAll(x => x.Id == id).Count;
            } while (count != 0);

            task.Id = id;
            lock(this)
            {
                tasks.Add(task);
            }
            return id;
        }

        public bool RemoveTask(int id)
        {
            var item= tasks.FirstOrDefault(x => x.Id == id);
            if(item!=null)
            {
                return tasks.Remove(item);
            }
            return false;
        }

        public ulong GetCurrentToken()
        {
            return watchToken;
        }
    }
}
